package cn.jjxx.modules.activiti.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import cn.jjxx.core.query.wrapper.EntityWrapper;
import cn.jjxx.core.utils.SpringContextHolder;
import cn.jjxx.core.utils.StringUtils;
import cn.jjxx.modules.activiti.service.impl.FlowService;
import cn.jjxx.modules.activiti.workflow.BillBean;
import cn.jjxx.modules.activiti.workflow.Config;
import cn.jjxx.modules.sms.service.ISmsSendLogService;
import cn.jjxx.modules.sys.entity.User;
import cn.jjxx.modules.sys.service.IUserService;
import cn.jjxx.modules.workflow.service.IFlowCommonService;

@Controller  
@Scope("prototype") 
public class ActivitiFlowService extends FlowService {

	@Autowired
	protected IFlowCommonService flowCommonService;
	@Autowired
	protected ISmsSendLogService smsSendLogService;
	@Autowired
	protected IUserService userService;
	
	/**
	 * @Description: 获取历史的提交人 .<br>
	 * @param executionId 执行Id.<br>
	 * @param taskDef task定义的键.<br>
	 * @author 郑成功 .<br>
	 * @date 2017-12-19 下午1:58:55.<br>
	 */
	public String checkIsSubmited(String executionId,String taskDef){
		List<HistoricTaskInstance> historyList = historyService.createHistoricTaskInstanceQuery()
				.executionId(executionId).taskDefinitionKey(taskDef).orderByTaskCreateTime().desc().list();
		if(historyList!=null&&historyList.size()>0){
			return historyList.get(0).getAssignee();
		}
		return null;
	}
	
	public boolean sendEmail(){
		return false;
	}
	
	/**
	 * @Description: 根据用户名获取用户 .<br>
	 * @param username 用户名.<br>
	 * @author 郑成功 .<br>
	 * @date 2018-11-22 上午10:36:40.<br>
	 */
	public User getUser(String username){
		EntityWrapper<User> wrapper = new EntityWrapper<User>(User.class);
		wrapper.eq("username", username);
		return userService.selectOne(wrapper);
	}
	
	/**
	 * @Description: 获取单据信息 .<br>
	 * @param billBean 流程配置单据.<br>
	 * @author 郑成功 .<br>
	 * @date 2018-11-21 下午4:58:16.<br>
	 */
	public Map<String,Object> getBillBeanInfo(BillBean billBean){
		String billId = billBean.getBillId();
		String idFeild = billBean.getIdFeild();
		Map<String,Object> billInfo = new HashMap<String, Object>();
		if(StringUtils.isNotEmpty(billBean.getCustomSql())){
			billInfo = flowCommonService.findCustomSql(billBean.getCustomSql());
		}else{
			billInfo = flowCommonService.findBillInfo(billId, billBean.getTableName(), idFeild);
		}
		return billInfo;
	}
	
	/**
	 * @Description: 同步系统用户到流程用户 .<br> .<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-7-26 上午10:49:58.<br>
	 */
	public void synchroSysUserToActUser(){
		flowCommonService.synchroSysUserToActUser();
	}
	
	/**
	 * @Description: 发送短信，并将短信日志写入数据库 .<br>
	 * @param executionId 流程执行Id.<br>
	 * @param phones 电话，多个用“,”分开.<br>
	 * @param content 发送内容模板.<br>
	 * @author 郑成功 .<br>
	 * @date 2018-7-25 下午5:37:00.<br>
	 */
	public boolean sendSMS(String executionId,String phones,String content,String sequeid){
		//获取单据信息
		BillBean billBean = runtimeService.getVariable(executionId, Config.variable.表单信息.toString(), BillBean.class);
		String submitorId = (String) runtimeService.getVariable(executionId, Config.constant.submitUser.toString());
		User user = userService.selectById(submitorId);
		String submitName = user.getRealname();
		Map<String,Object> billInfo = new HashMap<String, Object>();
		if(StringUtils.isNotEmpty(billBean.getCustomSql())){
			billInfo = flowCommonService.findCustomSql(billBean.getCustomSql());
		}else{
			billInfo = flowCommonService.findBillInfo(billBean.getBillId(), billBean.getTableName(), billBean.getIdFeild());
		}
		//获取流程发起人和流程发起时间
		billInfo.put("submitName", submitName);
		for (Entry<String, Object> entry : billInfo.entrySet()) {  
			  String key = entry.getKey();
			  String value = String.valueOf(entry.getValue());
			  if(content.contains("${"+key+"}")){
				  content = content.replace("${"+key+"}", value);
			  }
		  }
		smsSendLogService.writeSmsLog(phones, content, sequeid);
		return false;
	}
	
	/**
	 * @Description: 发送短信至流程提交人 .<br>
	 * @param proInstId 流程实例Id.<br>
	 * @param content 发送内容.<br>
	 * @param sequeid 发送序列号.<br>
	 * @author 郑成功 .<br>
	 * @date 2019-3-22 上午10:07:11.<br>
	 */
	public boolean sendSmsToSubmitor(String proInstId,String content,String sequeid){
		try {
			//获取流程单据的提交人
			HistoricProcessInstance proInst = historyService.createHistoricProcessInstanceQuery().processInstanceId(proInstId).singleResult();
			//获取提交人的手机号码
			String startUserId = proInst.getStartUserId();
			User user = userService.selectById(startUserId);
			String phone = user.getPhone();
			sendSMS(proInstId, phone, content, sequeid);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * @Description: 关闭流程 .<br>
	 * @param proInstId 实例Id.<br>
	 * @author 郑成功 .<br>
	 * @date 2019-3-22 上午10:06:52.<br>
	 */
	public boolean closeFlow(String proInstId){
		List<Task> tasks = taskService.createTaskQuery().processInstanceId(proInstId).list();
		if(tasks.size()>0){
			SpringContextHolder.getBean(WorkFlowController.class).endProcess(null, null, tasks.get(0).getId());
		}
		return true;
	}
	
	/**
	 * @Description: 自动完成任务 .<br>
	 * @param taskId 任务Id.<br>
	 * @author 郑成功 .<br>
	 * @date 2019-3-22 上午10:06:31.<br>
	 */
	public boolean AutoComplate(String taskId){
		return true;
	}
	
	/**
	 * @Description: 设置任务处理人为任务发起人 .<br>
	 * @param delegateTask 任务监听器.<br>
	 * @author 郑成功 .<br>
	 * @date 2019-3-22 上午10:02:41.<br>
	 */
	public boolean setAssigneeBySubmitter(DelegateTask delegateTask){
		try {
			//获取流程单据的提交人
			String proInstId = delegateTask.getProcessInstanceId();
			HistoricProcessInstance proInst = historyService.createHistoricProcessInstanceQuery().processInstanceId(proInstId).singleResult();
			//获取提交人
			String startUserId = proInst.getStartUserId();
			delegateTask.setAssignee(startUserId);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
}
